package com.transaction.demo.trade.service.impl;

import java.util.Date;

import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import lombok.extern.slf4j.Slf4j;

import com.transaction.demo.common.util.JsonUtils;
import com.transaction.demo.common.util.NotifyDestinationNameEnum;
import com.transaction.demo.common.util.Result;
import com.transaction.demo.common.util.ResultPage;
import com.transaction.demo.common.util.StringUtil;
import com.transaction.demo.message.MessageService;
import com.transaction.demo.message.vo.req.TransactionMessageAddReqVo;
import com.transaction.demo.trade.biz.TradePaymentOrderBiz;
import com.transaction.demo.trade.biz.TradePaymentRecordBiz;
import com.transaction.demo.trade.enums.ExceptionEnum;
import com.transaction.demo.trade.enums.TradeStatusEnum;
import com.transaction.demo.trade.exception.TradeServiceException;
import com.transaction.demo.trade.service.TradePaymentOrderService;
import com.transaction.demo.trade.vo.req.CompletePayReqVo;
import com.transaction.demo.trade.vo.req.InitPaymentOrderReqVo;
import com.transaction.demo.trade.vo.req.TradePaymentOrderListReqVo;
import com.transaction.demo.trade.vo.req.TradePaymentOrderReqVo;
import com.transaction.demo.trade.vo.req.TradePaymentOrderUpdateReqVo;
import com.transaction.demo.trade.vo.req.TradePaymentRecordReqVo;
import com.transaction.demo.trade.vo.req.TradePaymentRecordUpdateReqVo;
import com.transaction.demo.trade.vo.resp.TradePaymentOrderRespVo;
import com.transaction.demo.trade.vo.resp.TradePaymentRecordRespVo;

/**
 * 描述：支付订单表
 * 作者：马庆智
 * 日期：2023/04/27 17:22:10
 */
@Slf4j
@Service
public class TradePaymentOrderServiceImpl implements TradePaymentOrderService {

	@Autowired
	private TradePaymentOrderBiz tradePaymentOrderBiz;

	@Autowired
	private TradePaymentRecordBiz tradePaymentRecordBiz;

	@Autowired
	private MessageService messageService;

	/**
	 * 初始化订单
	 *
	 * @param record 请求参数
	 * @return TradePaymentOrderResp
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public Result<String> initPaymentOrder(InitPaymentOrderReqVo record) {
		log.info("初始化订单参数: {}", JsonUtils.toJson(record));
//
//		tradePaymentOrderBiz.saveTradePaymentOrder(record);
//
//		tradePaymentRecordBiz.saveTradePaymentRecord(record);
		return null;
	}

	/**
	 * 完成支付
	 *
	 * @param record 请求参数
	 * @return TradePaymentOrderResp
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public Result<String> completePay(CompletePayReqVo record) {

		String businessId = record.getBusinessId();
		//模拟1的时候是成功
		boolean b = "1".equals(record.getStatus());

		TradePaymentOrderRespVo respVo = tradePaymentOrderBiz.queryTradePaymentOrder(
				TradePaymentOrderReqVo.builder().merchantOrderNo(businessId).build());

		//1.校验订单信息
		if (respVo == null) {
			log.info("非法订单,订单{}不存在", businessId);
			return Result.error();
		}

		if (TradeStatusEnum.SUCCESS.name().equals(respVo.getStatus())) {
			log.info("订单{}为成功状态,不做业务处理", businessId);
			return Result.success();
		}

		if (!TradeStatusEnum.WAITING_PAYMENT.name().equals(respVo.getStatus())) {
			log.info("订单{}状态为非等待支付状态,不做业务处理", businessId);
			return Result.error();
		}

		//场景一：模拟发送异常,或者消息服务异常
		//throw new TradeServiceException(ExceptionEnum.MESSAGE_ERROR.getCode(), "发送异常,或者消息服务异常");

		//2.发送预存消息
		String messageId = saveMessageWaitingConfirm(record);

		//场景二: 返回预存成功后,操作失败
		//throw new TradeServiceException(ExceptionEnum.MESSAGE_ERROR.getCode(), "返回预存成功后,操作失败");
		//3.更新订单相关状态
		updateStatus(businessId, b, respVo);

		//场景三: 返回预存成功后,操作成功,后再次发送mq失败
		//throw new TradeServiceException(ExceptionEnum.MESSAGE_ERROR.getCode(), "返回预存成功后,操作成功, 后再次发送mq失败");
		//4.确认消息
		log.info("确认消息：{}", messageId);
		messageService.confirmAndSendMessage(messageId);
		return Result.success();
	}

	/**
	 * 更新订单状态和支付记录状态
	 *
	 * @param businessId 业务编号
	 * @param b 是否成功
	 * @param respVo 原始订单信息
	 * @author 马庆智
	 * @date: 2023/5/16 17:04
	 */
	private void updateStatus(String businessId, boolean b, TradePaymentOrderRespVo respVo) {
		// 修改支付记录状态
		TradePaymentOrderUpdateReqVo updateReqVo = new TradePaymentOrderUpdateReqVo();
		BeanUtils.copyProperties(respVo, updateReqVo);
		updateReqVo.setEditTime(new Date());
		updateReqVo.setStatus(b ? TradeStatusEnum.SUCCESS.name() : TradeStatusEnum.FAILED.name());
		log.info("更新订单信息：{}", JsonUtils.toJson(updateReqVo));
		tradePaymentOrderBiz.updateTradePaymentOrder(updateReqVo);

		// 修改支付订单状态
		TradePaymentRecordRespVo recordRespVo = tradePaymentRecordBiz.queryTradePaymentRecord(
				TradePaymentRecordReqVo.builder().merchantOrderNo(businessId).build());
		TradePaymentRecordUpdateReqVo recordUpdateReqVo = new TradePaymentRecordUpdateReqVo();
		BeanUtils.copyProperties(recordRespVo, recordUpdateReqVo);
		recordUpdateReqVo.setEditTime(new Date());
		recordUpdateReqVo.setStatus(b ? TradeStatusEnum.SUCCESS.name() : TradeStatusEnum.FAILED.name());
		log.info("更新支付记录信息：{}", JsonUtils.toJson(recordUpdateReqVo));
		tradePaymentRecordBiz.updateTradePaymentRecord(recordUpdateReqVo);
	}

	/**
	 * 发送预发消息
	 *
	 * @param record 参数
	 * @return messageId
	 * @author 马庆智
	 * @date: 2023/5/16 17:02
	 */
	@NotNull
	private String saveMessageWaitingConfirm(CompletePayReqVo record) {

		String messageId = StringUtil.get32UUID();
		TransactionMessageAddReqVo messageAddReqVo = new TransactionMessageAddReqVo();
		record.setMessageId(messageId);
		messageAddReqVo.setMessageId(messageId);
		messageAddReqVo.setMessageBody(JsonUtils.toJson(record));
		messageAddReqVo.setConsumerQueue(NotifyDestinationNameEnum.ACCOUNTING_NOTIFY.name());
		log.info("发送预发消息：{}", JsonUtils.toJson(messageAddReqVo));
		messageService.saveMessageWaitingConfirm(messageAddReqVo);

		return messageId;
	}

	/**
	 * 查询支付订单表
	 *
	 * @param tradePaymentOrder 请求参数
	 * @return TradePaymentOrderResp
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public TradePaymentOrderRespVo queryTradePaymentOrder(TradePaymentOrderReqVo tradePaymentOrder) {

		return tradePaymentOrderBiz.queryTradePaymentOrder(tradePaymentOrder);
	}

	/**
	 * 查询支付订单表列表
	 *
	 * @param tradePaymentOrder 请求参数
	 * @return TradePaymentOrderResp
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public ResultPage<TradePaymentOrderRespVo> queryTradePaymentOrderList(
			TradePaymentOrderListReqVo tradePaymentOrder) {

		return tradePaymentOrderBiz.queryTradePaymentOrderList(tradePaymentOrder);
	}

	/**
	 * 删除支付订单表
	 *
	 * @param ids 请求参数
	 * @return int
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public int deleteTradePaymentOrder(String ids) {
		return tradePaymentOrderBiz.deleteTradePaymentOrder(ids);
	}

	/**
	 * 更新支付订单表
	 *
	 * @param tradePaymentOrder 请求参数
	 * @return int
	 * @author 马庆智
	 * @date: 2023/04/27 17:22:10
	 */
	@Override
	public int updateTradePaymentOrder(TradePaymentOrderUpdateReqVo tradePaymentOrder) {

		return tradePaymentOrderBiz.updateTradePaymentOrder(tradePaymentOrder);
	}

}